﻿#include "SDL_Platform.h"
#include "SDL_Canvas.h"

#define CLO_SDL_INIT_FLAG		SDL_INIT_VIDEO | SDL_INIT_TIMER

SDL_CPlatform::SDL_CPlatform()
{
	m_pMainSurface = NULL;
}

SDL_CPlatform::~SDL_CPlatform()
{
}

bool SDL_CPlatform::InitPlatform(GAF_CBundle* pParam)
{
	// 初始化SDL
	if(SDL_WasInit(CLO_SDL_INIT_FLAG) == 0)
	{
		if(SDL_Init(CLO_SDL_INIT_FLAG) == -1)
		{
			GAF_ERROR("Init SDL Error!\n", "");
			return false;
		}
	}

	// 初始化TTF
	if(TTF_Init() == -1)
	{
		GAF_ERROR("Init SDL_TTF Error!\n", "");
		return false;
	}

	return true;
}

bool SDL_CPlatform::DestroyPlatform()
{
	atexit(SDL_Quit);	// 程序崩溃时，也可以卸载SDL
	atexit(TTF_Quit);	// 程序崩溃时，也可以卸载SDL_TTF

	return true;
}

GAF_DWindowHandle SDL_CPlatform::NewWindow(GAF_SCreateWindow& cw)
{
	GAF_CHECK_R(m_pMainSurface == NULL, NULL);

	SDL_Surface* _hSDLWindow = NULL;

	unsigned long _lVideoFlags = 0;
	
	// 硬加速
	if(cw.isHardware)
		_lVideoFlags |= SDL_HWSURFACE;		// 显卡加速		
	else
		_lVideoFlags |= SDL_SWSURFACE;		// CPU加速

	// 全屏幕
	if(cw.isFullScreen)
	{
		_lVideoFlags |= SDL_FULLSCREEN;
		SDL_ShowCursor(0);
	}

	SDL_DPixelBit _pb = cw.bdlOther.GetInteger("PixelBit");
	if((_hSDLWindow = SDL_SetVideoMode(cw.nWidth, cw.nHeight, _pb, _lVideoFlags)) == NULL)
		return NULL;

	if(m_pMainSurface == NULL)
	{
		m_pMainSurface = _hSDLWindow;
	}

	SetWindowTitle(m_pMainSurface, cw.strTitle);

	return _hSDLWindow;
}

bool SDL_CPlatform::ShowWindow(GAF_DWindowHandle hWindow)
{
	return true;
}

bool SDL_CPlatform::HideWindow(GAF_DWindowHandle hWindow)
{
	return true;
}

void SDL_CPlatform::RanderWindow(GAF_DWindowHandle hWindow)
{
	return;
}

void SDL_CPlatform::FlipWindow(GAF_DWindowHandle hWindow)
{
	SDL_Flip((SDL_Surface*)hWindow);
}

bool SDL_CPlatform::DeleteWindow(GAF_DWindowHandle hWindow)
{
	SDL_DWindowHandle _hSDLWindow = (SDL_DWindowHandle)hWindow;
	if(m_pMainSurface == _hSDLWindow)
	{
// 		SAFE_RELEASE(m_pMainSurface);
	}
	else
	{
// 		SAFE_RELEASE(_hSDLWindow);
	}

	return true;
}

void SDL_CPlatform::SetWindowTitle(GAF_DWindowHandle hWindow, _STRING strTitle)
{
	GAF_CHECK(strTitle != "");

	SDL_WM_SetCaption(strTitle.c_str(), NULL);
}

GAF_CCanvas* SDL_CPlatform::NewCanvas(GAF_DWindowHandle pWndHandle)
{
	//?? 删除指针有问题

	GAF_CCanvas* pCanvas = new SDL_CCanvas(); //GAF_NEW(SDL_CCanvas);

	if(!pCanvas->Init(pWndHandle))
	{
		delete pCanvas; //GAF_DELETE(pCanvas);
	}

	return pCanvas;
}

bool SDL_CPlatform::DeleteCanvas(GAF_CCanvas* pCanvas)
{
	delete pCanvas; //GAF_DELETE(pCanvas);
	return true;
}

bool SDL_CPlatform::GetCommand(GAF_DWindowHandle pWndHandle, GAF_SCommand& cmdGet)
{
	static SDL_Event s_SDLEvent;

	if(SDL_PollEvent(&s_SDLEvent) == 1)
	{
// 		GAF_NOTE("SDL Command Type = %d\n", s_SDLEvent.type);

		cmdGet.Reset();

		switch(s_SDLEvent.type)
		{
		case SDL_QUIT:
			cmdGet.nCmdID = GAF_COMMAND_QUIT;
			break;


		case SDL_KEYDOWN:
			cmdGet.nCmdID = GAF_COMMAND_KEY_DOWN;
			cmdGet.lParam1 = cmdGet.lParam2 = (long)s_SDLEvent.key.keysym.sym;
			break;
		case SDL_KEYUP:
			cmdGet.nCmdID = GAF_COMMAND_KEY_UP;
			cmdGet.lParam1 = cmdGet.lParam2 = (long)s_SDLEvent.key.keysym.sym;
			break;
		case SDL_MOUSEBUTTONDOWN:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_DOWN;
			cmdGet.lParam1 = (long)s_SDLEvent.button.button;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.button.x, s_SDLEvent.button.y);
			break;
		case SDL_MOUSEBUTTONUP:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_UP;
			cmdGet.lParam1 = (long)s_SDLEvent.button.button;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.button.x, s_SDLEvent.button.y);
			break;
		case SDL_MOUSEMOTION:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_MOVE;
			cmdGet.lParam1 = (long)s_SDLEvent.motion.state;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.motion.x, s_SDLEvent.motion.y);
			break;
		default:
			return false;
		}
		return true;
	}
	return false;
}

void SDL_CPlatform::CleanCommandBuffer(GAF_DWindowHandle pWndHandle)
{
	SDL_Event SDLEvent;
	while(SDL_PollEvent(&SDLEvent) == 1)
	{}
}

GAF_DTimeTicks SDL_CPlatform::GetTimeTicks()
{
	return SDL_GetTicks();
}

void SDL_CPlatform::Delay(GAF_DTimeTicks ttSleep)
{
	return SDL_Delay(ttSleep);
}

GAF_DImageHandle SDL_CPlatform::NewImage(
		const _STRING strPathName,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		GAF_SImageInfo& _OUT ii
	)
{
	SDL_Surface* pLoad = NULL;
	pLoad = IMG_Load(strPathName.c_str());

	if(pLoad != NULL)
	{
		pLoad = SurfaceFormat(pLoad);

		nWidth = pLoad->w;
		nHeight = pLoad->h;
		SDL_DPixelBit pb = pLoad->format->BitsPerPixel;

		ii.nWidth = nWidth;
		ii.nHeight = nHeight;
		ii.bdlOther.PutInteger("PixelBit", pb);
	}

	return pLoad;
}
GAF_DImageHandle SDL_CPlatform::NewImage(
		const void* pData,
		const SIZET nSize,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		GAF_SImageInfo& _OUT ii
	)
{
	SDL_RWops* pRW = SDL_RWFromMem((void*)pData, nSize);

	SDL_Surface* pLoad = NULL;
	pLoad = IMG_Load_RW(pRW, 0);

	if(pLoad != NULL)
	{
		pLoad = SurfaceFormat(pLoad);

		nWidth = pLoad->w;
		nHeight = pLoad->h;
		SDL_DPixelBit pb = pLoad->format->BitsPerPixel;

		ii.nWidth = nWidth;
		ii.nHeight = nHeight;
		ii.bdlOther.PutInteger("PixelBit", pb);
	}

	return pLoad;
}

GAF_DImageHandle SDL_CPlatform::NewImage(
		const UINT nWidth,
		const UINT nHeight,
		GAF_SImageInfo& _OUT ii
	)
{
	SDL_Surface* pCreate = NULL;

	pCreate = SDL_CreateRGBSurface(SDL_HWSURFACE, nWidth, nHeight, SDL_PIXELBIT_32,
		m_pMainSurface->format->Rmask, m_pMainSurface->format->Gmask,
		m_pMainSurface->format->Bmask, m_pMainSurface->format->Amask);

	if(pCreate != NULL)
	{
		pCreate = SurfaceFormat(pCreate);

		ii.nWidth = nWidth;
		ii.nHeight = nHeight;
		ii.bdlOther.PutInteger("PixelBit", SDL_PIXELBIT_32);
	}

	return pCreate;
}

bool SDL_CPlatform::GetImageInfo(
		GAF_DImageHandle hImage,
		UINT& _OUT nWidth,
		UINT& _OUT nHeight,
		GAF_SImageInfo& _OUT ii
	)
{
	GAF_CHECK_R(hImage != NULL, false);

	SDL_Surface* pImage = (SDL_Surface*)hImage;
	nWidth = pImage->w;
	nHeight = pImage->h;
//	pb = pImage->format->BitsPerPixel;
	return true;
}

bool SDL_CPlatform::DeleteImage(GAF_DImageHandle poiCur)
{
	GAF_CHECK_R(poiCur != NULL, false);
	SDL_FreeSurface((SDL_Surface*)poiCur);
	return true;
}

// GAF_CAudio* SDLPlatform::CreateAudio(GAF_CBundle* pBundle)
// {
// 	CSDLAudio* pAudio = GAF_NEW(CSDLAudio);
// 
// 	if(!pAudio->Init(pBundle))
// 	{
// 		CLO_ERROR_INIT_CLASS(CLO_CSDLAudio);
// 		GAF_DELETE(pAudio);
// 		return NULL;
// 	}
// 	
// 	return pAudio;
// }
// 
// bool SDLPlatform::PlayAudio(const _STRING strPathName, bool isLoop)
// {
// 	return false;
// }



SDL_Surface* SDL_CPlatform::SurfaceFormat(SDL_Surface* pSrc)
{
	SDL_Surface* pReturn = NULL;
	if(pSrc != NULL)
	{
		pReturn = pSrc;
// 		pReturn = SDL_DisplayFormatAlpha(pSrc);
// 		SDL_FreeSurface(pSrc);
	}
	return pReturn;
}
